#! /usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
from ib.ext.Contract import Contract
from ib.opt import ibConnection, message
from time import sleep, localtime, strftime, strptime, mktime, localtime
import datetime
from ib.ext.Order import Order
from ib.ext.ComboLeg import ComboLeg
from ib.ext.ContractDetails import ContractDetails

conId = -1
nextOrderId = -1
startTime = ''

hasPosition = False
tradeSize = 2
# define the grid box
gridupper, gridlower = -1., -1.
bid, ask = -1., -1.

pricelist = []
acnt = [0.0, 0.0, 0.0]
stkPosition = {}
optPosition = {}
futPosition = {}
openOrder = {}
bid, ask, last = 0., 0., 0.
l2ask = [(0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0)]
l2bid = [(0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0), (0.0, 0)]
openRange = [0.0, 0.0]
oneminBar, fiveminBar, fifteenminBar = [], [], []

stpOffset = 0.50
size_15ors = 1


# might not be efficient
"""
class openOrder(object):
    # maintain a list of orders IB API generated.
    # this id is different with permId
    m_contract = Contract()
    m_status = ""
    m_filled = int()
    m_remaining = int()
    m_avgFillPrice = float()
    # reserve it for now
    #permId = 0
    #parentId = 0
    #lastFilledPrice = 0.0
    #clientId = 0

    def __init__(self):
        self.m_status = ""
        self.m_filled = 0
        self.m_remaining = 0
        self.m_avgFillPrice = 0.0

    def __eq__(self, p_other):
        if self is p_other:
            return True
        if p_other is None:
            return False
        l_theOther = p_other
        #if (self.m_permId == l_theOther.m_permId):
            #return True
        if (self.m_contract != l_theOther.m_contract):
            return False
        return True
"""

def make_openOrder(contract, status, filled, remaining, avgFillPrice):
    newopenOrder = openOrder()
    newopenOrder.m_contract = contract
    newopenOrder.m_status = status
    newopenOrder.m_filled = filled
    newopenOrder.m_remaining = remaining
    newopenOrder.m_avgFillPrice = avgFillPrice
    return newopenOrder

def moving_average(x, n, type='simple'):
    '''
    compute an n period moving average.
    type is 'simple' | 'exponential'

    '''
    x = np.asarray(x)
    if type=='simple':
        weights = np.ones(n)
    else:
        weights = np.exp(np.linspace(-1., 0., n))

    weights /= weights.sum()


    a =  np.convolve(x, weights, mode='full')[:len(x)]
    a[:n] = a[n]
    return a

def watcher(msg):
    print msg

def NextValidIdHandler(msg):
    global nextOrderId
    nextOrderId = msg.orderId

def getCurrentTime(msg):
    global startTime
    # confirm: local time on machine or server time???
    time_s =  localtime(int(msg.time))
    #startTime = strftime(localtime(int(msg.time)), '%Y%m%d %H:%M')
    # compare with machine time
    startTime = str(time_s.tm_year) + str(time_s.tm_mon).zfill(2) + str(time_s.tm_mday).zfill(2) + ' '\
            + str(time_s.tm_hour).zfill(2) + ':' + str(time_s.tm_min).zfill(2) + ':' + str(time_s.tm_sec).zfill(2)
    currentTime = strftime("%Y%m%d %H:%M:%S", localtime())
    print startTime
    #print currentTime

def ContractDetailsHandler(msg):
    global contractDetails
    contractDetails = msg.contractDetails

def my_BidAsk(msg):
    if msg.field == 1:
        print '%s:%s: bid: %s' % (contractTuple[0], contractTuple[6], msg.price)
    elif msg.field == 2:
        print '%s:%s: ask: %s' % (contractTuple[0], contractTuple[6], msg.price)

def print_account():
    global acnt
    print 'BBC', acnt[0]
    print 'PNL', acnt[1]
    print 'BP', acnt[2]

def update_account(msg):
    global acnt
    if msg.key == 'NetLiquidationByCurrency' and msg.currency == 'BASE':
        acnt[0] = float(msg.value)
    if msg.key == 'UnrealizedPnL' and msg.currency == 'BASE':
        acnt[1] = float(msg.value)
    if msg.key == 'BuyingPower':
        acnt[2] = float(msg.value)

def update_port(msg):
    global stkPosition, optPosition
    if msg.contract.m_secType == 'STK':
        stkPosition[msg.contract.m_symbol] = (msg.position, msg.averageCost, msg.marketPrice, msg.unrealizedPNL)
    if msg.contract.m_secType == 'OPT':
        optPosition[(msg.contract.m_symbol, msg.contract.m_right, msg.contract.m_expiry, msg.contract.m_strike)] = (msg.position, msg.averageCost, msg.marketPrice, msg.unrealizedPNL)
    if msg.contract.m_secType == 'FUT':
        futPosition[(msg.contract.m_symbol, msg.contract.m_expiry)] = (msg.position, msg.averageCost, msg.marketPrice, msg.unrealizedPNL)

def update_oneminBar(msg):
    global oneminBar
    if 'finished' not in msg.date:
        oneminBar.append((msg.date, msg.open, msg.high, msg.low, msg.close, msg.volume, msg.count, msg.WAP))
        print msg.date, msg.open, msg.high, msg.low, msg.close, msg.volume, msg.count, msg.WAP

def update_fiveminBar(msg):
    global fiveminBar
    if 'finished' not in msg.date:
        fiveminBar.append((msg.date, msg.open, msg.high, msg.low, msg.close, msg.volume, msg.count, msg.WAP))
        print msg.date, msg.open, msg.high, msg.low, msg.close, msg.volume, msg.count, msg.WAP

def update_fifteenminBar(msg):
    global fifteenminBar
    if 'finished' not in msg.date:
        fifteenminBar.append((msg.date, msg.open, msg.high, msg.low, msg.close, msg.volume, msg.count, msg.WAP))
        print msg.date, msg.open, msg.high, msg.low, msg.close, msg.volume, msg.count, msg.WAP

def update_openRange(msg):
    global openRange, size_15ors, futContract, stpOffset, nextOrderId, openOrder
    if 'finished' not in msg.date:
        openRange[0] = msg.high
        openRange[1] = msg.low

    if 'finished' in msg.date:
        price_h = openRange[0] + stpOffset
        order_t = makeOrder('Buy', 'STPLMT', size_15ors, price_h, 0, price_h)
        con.placeOrder(nextOrderId, futContract, order_t)
        openOrder[nextOrderId] = [futContract, 'Submitted', size_15ors, 0, 'Buy', False]
        nextOrderId = nextOrderId + 1

        price_l = openRange[1] - stpOffset
        order_t = makeOrder('Sell', 'STPLMT', size_15ors, price_l, 0, price_l)
        con.placeOrder(nextOrderId, futContract, order_t)
        openOrder[nextOrderId] = [futContract, 'Submitted', size_15ors, 0, 'Sell', False]
        nextOrderId = nextOrderId + 1

def update_openOrder(msg):
    global openOrder, nextOrderId
    if len(openOrder) > 0:
        if msg.status == 'Filled':
            protected_t = openOrder[msg.orderId][6]
            if not protected_t:
                status_t = msg.status
                filled_t = msg.filled
                remaining_t = msg.remaining
                avgFillPrice_t = msg.avgFillPrice
                #print openOrder
                contract_t = openOrder[msg.orderId][0]
                #print contract
                #print msg.orderId
                openOrder[msg.orderId][1] = status_t
                openOrder[msg.orderId][2] = filled_t
                openOrder[msg.orderId][3] = remaining_t
                openOrder[msg.orderId][4] = avgFillPrice_t
                if openOrder[msg.orderId][5] == 'Sell':
                    order_t = 'Buy'
                    price_t = avgFillPrice_t + 2.25
                    trailStopPrice_t = avgFillPrice_t + 2.0
                    auxPrice_t = 2.0
                    order_t = makeOrder(order_t, 'TRAILLIMIT', filled_t, price_t, trailStopPrice_t, auxPrice_t)
                    con.placeOrder(nextOrderId, contract_t, order_t)
                    openOrder[msg.orderId][6] = True
                    # the order status will be repeated three times, sleep one second to avoid multiple submittion
                    nextOrderId = nextOrderId + 1
                if openOrder[msg.orderId][5] == 'Buy':
                    order_t = 'Sell'
                    price_t = avgFillPrice_t - 2.25
                    trailStopPrice_t = avgFillPrice_t - 2.0
                    auxPrice_t = 2.0
                    order_t = makeOrder(order_t, 'TRAILLIMIT', filled_t, price_t, trailStopPrice_t, auxPrice_t)
                    con.placeOrder(nextOrderId, contract_t, order_t)
                    openOrder[msg.orderId][6] = True
                    nextOrderId = nextOrderId + 1

def updateMktDepth(msg):
    global l2ask, l2bid, ask, bid
    if msg.side == 0:
        l2ask[msg.position] = (msg.price, msg.size)
    if msg.side == 1:
        l2bid[msg.position] = (msg.price, msg.size)
    ask, bid = l2ask[0][0], l2bid[0][0]

def printMktDepth():
    #global l2ask, l2bid
    """
    # print the whole depth
    for i in range(10):
        print '%.2f -- %d' % (l2ask[9-i][0], l2ask[9-i][1])
        
    print "---------------"
    
    for i in range(10):
        print '%.2f -- %d' % (l2bid[i][0], l2bid[i][1])
    """
    # print the bid/ask only

    global bid, ask
    print bid, ask


def print_port():
    global stkPosition, optPosition, futPosition
    print "\nStock Positions are: "
    for con, pos in stkPosition.iteritems():
        print con, pos[0], pos[1], pos[2], pos[3]

    print "\nOptions Positions are: "
    for con, pos in optPosition.iteritems():
        print con, pos[0], pos[1], pos[2], pos[3]

    print "\nFutures Positions are: "
    for con, pos in futPosition.iteritems():
        print con, pos[0], pos[1], pos[2], pos[3]

    """
    if msg.contract.m_secType == 'OPT':
        print msg.contract.m_conId, msg.contract.m_symbol, msg.contract.m_right, msg.contract.m_expiry, msg.contract.m_strike, msg.contract.m_right, msg.position, msg.unrealizedPNL
    if msg.contract.m_secType == 'STK':
        print msg.contract.m_conId, msg.contract.m_symbol, msg.position, msg.unrealizedPNL
    """
    #_con.register(watcher)
    #_con.reqContractDetails()

def print_openOrder():
    global openOrder
    print "\nOpen Orders are: "
    for con, order_s in openOrder.iteritems():
        print con, order_s[0], order_s[1], order_s[2], order_s[3], order_s[4]

def print_price(msg):
    #global pricelist
    if msg.field == 4:
        print msg.price
        #pricelist.append(msg.price)
        #sleep(1)

def print_option_chain(msg):
    print '%s, %s, %s, %s' % (msg.contractDetails.m_summary.m_conId, msg.contractDetails.m_summary.m_right, msg.contractDetails.m_summary.m_strike, msg.contractDetails.m_summary.m_expiry)

def get_realtimebar(msg):
    global pricelist
    print '%s, %f' % (msg.time, msg.wap)
    pricelist.append(msg.wap)

def makeStkContract(sym):
    newStkContract = Contract()
    newStkContract.m_symbol = sym
    newStkContract.m_secType = 'STK'
    newStkContract.m_strike = 0.00
    newStkContract.m_exchange = 'SMART'
    newStkContract.m_currency = 'USD'
    return newStkContract

def makeOptContract(_optStr):
    newContract = Contract()
    #_opt = _optStr.split(' ')
    newContract.m_symbol = _optStr
    newContract.m_secType = 'OPT'
    newContract.m_exchange = 'SMART'
    newContract.m_currency = 'USD'
    #newContract.m_expiry = _opt[1]
    #newContract.m_strike = _opt[2][1:]
    #newContract.m_right = _opt[2][0]
    return newContract

def makeOptContract2(_optStr):
    newContract = Contract()
    _opt = _optStr.split(' ')
    newContract.m_symbol = _opt[0]
    newContract.m_secType = 'OPT'
    newContract.m_exchange = 'SMART'
    newContract.m_currency = 'USD'
    newContract.m_expiry = _opt[1]
    newContract.m_strike = _opt[2][1:]
    newContract.m_right = _opt[2][0]
    return newContract

def makeFutContract(symbol, exchange, expiry):
    newContract = Contract()
    newContract.m_symbol = symbol
    newContract.m_secType = 'FUT'
    newContract.m_exchange = exchange
    newContract.m_currency = 'USD'
    newContract.m_expiry = expiry
    #newContract.m_strike = ''
    #newContract.m_right = ''
    return newContract

def printOptQuote(msg):
    bid, ask, last = 0., 0., 0.
    if msg.field == 1:
        bid = msg.price
    if msg.field == 2:
        ask = msg.price
    if msg.field == 4:
        last = msg.price
    print '%.2f, %.2f %.2f' % (bid, ask, last)

def printFutQuote(msg):
    if msg.field == 1:
        #print '%s:%s:bid: %s' % (contractTuple[0], contractTuple[6], msg.price)
        print 'bid: %s' % (msg.price)
    elif msg.field == 2:
        #print '%s:%s:ask: %s' % (contractTuple[0], contractTuple[6], msg.price)
        print 'ask: %s' % (msg.price)
    elif msg.field == 4:
        #print '%s:%s:last: %s' % (contractTuple[0], contractTuple[6], msg.price)
        print 'last: %s' % (msg.price)
    elif msg.field == 22:
        print 'open interest: %s' % msg

def makeStkOrder(action, orderID, orderType):
    newOptOrder = Order()
    newOptOrder.m_orderId = orderID
    newOptOrder.m_clientId = 0
    newOptOrder.m_permid = 0
    newOptOrder.m_action = action
    newOptOrder.m_lmtPrice = 0
    newOptOrder.m_auxPrice = 0
    newOptOrder.m_tif = 'DAY'
    newOptOrder.m_transmit = False
    newOptOrder.m_orderType = 'MKT'
    newOptOrder.m_totalQuantity = 100
    return newOptOrder

def makeOptOrder(orderID, action, lmtprice, quantity=2):
    newStkOrder = Order()
    newStkOrder.m_orderId = orderID
    newStkOrder.m_cliendId = 0
    newStkOrder.m_permid = 0
    newStkOrder.m_action = action
    newStkOrder.m_lmtPrice = lmtprice
    newStkOrder.m_tif = 'DAY'
    newStkOrder.m_transmit = True
    newStkOrder.m_orderType = 'LMT'
    newStkOrder.m_totalQuantity = quantity
    return newStkOrder

def makeOptLeg(conId, action):
    newComboLeg = ComboLeg()
    newComboLeg.m_conId = conId
    newComboLeg.m_ratio = 1
    newComboLeg.m_action = action
    newComboLeg.m_exchange = 'SMART'
    newComboLeg.m_openClose = 0
    newComboLeg.m_shortSaleSlot = 0
    newComboLeg.m_destinatedLocation = ''
    return newComboLeg

def makeBagContract(sym, legs):
    newBagContract = Contract()
    newBagContract.m_symbol = sym
    newBagContract.m_secType = 'BAG'
    newBagContract.m_exchange = 'SMART'
    newBagContract.m_currency = 'USD'
    newBagContract.m_comboLegs = legs
    return newBagContract

def makeOrder(pid,  action, tp, qty, price, trailStopPrice = 0.0, auxPrice = 0.0):
    newOrder = Order()
    newOrder.m_orderId = NextValidIdHandler
    newOrder.m_action = action
    newOrder.m_totalQuantity = qty
    newOrder.m_orderType = tp
    newOrder.m_lmtPrice = price
    newOrder.m_auxPrice = 0
    newOrder.m_tif = 'DAY'
    newOrder.m_trailStopPrice = trailStopPrice
    newOrder.m_auxPrice = auxPrice
    newOrder.m_triggerMethod = 0
    newOrder.m_outsideRth = True
    newOrder.m_parentId = pid
    #newOrder.m_discretionaryAmt = 0.
    newOrder.m_transmit = True
    return newOrder

def getNextValidOrderId(msg):
    global orderId
    orderId = msg.orderId
    #orderId = orderId + 1

def getConId(contract):
    global contractDetails
    # reserve reqId = 9 for contract Id
    con.reqContractDetails(9, contract)
    #con.reqContractDetails(contract)
    # wait for TWS message to come back to message handler
    contractDetails = ContractDetails()
    while contractDetails.m_summary.m_conId == 0:
        sleep(1)

    return contractDetails.m_summary.m_conId

def print_open_order(msg):
    #if msg.key == 'OpenOrder':
        #print '%s,%s,%s,%s,%s -- %s' % (msg.orderId, msg.contract.m_symbol, msg.contract.m_expiry,\
            #msg.contract.m_right, msg.contract.m_strike, msg.orderState.m_status)
    #print '%s,%s,%s,%s,%s -- %s' % (msg.orderId, msg.contract.m_symbol, msg.contract.m_expiry,\
            #msg.contract.m_right, msg.contract.m_strike, msg.orderState.m_status)
    print msg

def do_trade():
    if hasPosition:
    #if hasPosition or hasPending:
        return 0
    # Strategy here
    else:
        return 1

def submit_order(type):
    global bid,  ask,  futContract,  nextOrderId
    
    #Trailing stop orders can be attached to limit or stop-limit orders only.-
    if type == 1:
        order_parent = makeOrder(0, "Buy",  "STP",  tradeSize,  bid+1.0,  0.0,  0)
        order_stoploss = makeOrder(nextOrderId, "Sell",  "TRAIL", tradeSize ,  0, bid - 1.0,  1.0)   
        order_profittaking = makeOrder(nextOrderId, "Sell",  "LMT", tradeSize,  ask + 5.0,  0,  0)
        con.placeOrder(nextOrderId, futContract, order_parent)
        nextOrderId = nextOrderId + 1
        con.placeOrder(nextOrderId, futContract,  order_stoploss)
        nextOrderId = nextOrderId + 1
        con.placeOrder(nextOrderId, futContract,  order_profittaking)
        nextOrderId = nextOrderId + 1
        #openOrder[msg.orderId][6] = True
                    # the order status will be repeated three times, sleep one second to avoid multiple submittion

def update_historicalBar(msg):
    # there are two minutes delay in historical Bar data request

    global nextOrderId, time_s, time_t, oneminBar, fiveminBar, fifteenminBar, futContract
    #print strftime('%H:%M:%S', localtime(msg.time))
    hour_c = localtime(msg.time)[3]
    min_c = localtime(msg.time)[4]
    sec_c = localtime(msg.time)[5]

    print hour_c, min_c, sec_c
    if sec_c == 0:
        time_t = strftime('%Y%m%d %H:%M:%S', localtime(msg.time))
        con.register(update_oneminBar, message.HistoricalData)
        con.reqHistoricalData(reqIdHistoricalData1, futContract, time_t, '600 S', '1 min', 'TRADES', 0, 1)
        if do_trade() == -1:
            submit_order(-1)
        elif do_trade () == 1:
            submit_order(1)
        else:
            pass

    #if sec_c == 10 and (min_c-2)%5 == 0:
        #time_t = strftime('%Y%m%d %H:%M:%S', localtime(msg.time-10))
        #con.register(update_fiveminBar, message.HistoricalData)
        #con.reqHistoricalData(reqIdHistoricalData1, futContract, time_t, '1 D', '5 mins', 'TRADES', 0, 1)

    #if sec_c == 0 and (min_c)%5 == 0:
        #time_t = strftime('%Y%m%d %H:%M:%S', localtime(msg.time))
        #con.register(update_fiveminBar, message.HistoricalData)
        #con.reqHistoricalData(reqIdHistoricalData1, futContract, time_t, '2 D', '5 mins', 'TRADES', 0, 1)

    #if sec_c == 20 and (min_c-2)%15 == 0:
        #con.register(update_fifteenminBar, message.HistoricalData)
        #time_t = strftime('%Y%m%d %H:%M:%S', localtime(msg.time-20))
        #con.reqHistoricalData(reqIdHistoricalData1, futContract, time_t, '1 D', '15 mins', 'TRADES', 0, 1)

    #print localtime(msg.time)
    #print time_s
    #if msg.time == long(time_s):
    #if msg.time > long(time_s):
        #con.register(watcher)
        #print time_t
        #con.register(update_fiveminBar, message.HistoricalData)
        #sleep(1)
        #con.cancelHistoricalData(reqIdHistoricalData1)
        #print fiveminBar

    """
    if str(msg.time)[len(str(msg.time))-1] == '0':
        optOrder = makeOrder('BUY', 'MKT', 1, 0.0)
        con.placeOrder(nextOrderId, futContract, optOrder)
        nextOrderId = nextOrderId + 1
    else:
        optOrder = makeOrder('SELL', 'MKT', 1, 0.0)
        con.placeOrder(nextOrderId, futContract, optOrder)
        nextOrderId = nextOrderId + 1
    #print int(msg.time)
    """

if __name__ == '__main__':
    #global stkPosition, optPosition, futPosition
    con = ibConnection()
    #con.host = '69.120.101.173'
    #con.host = '127.0.0.1'
    #con.host = '69.120.108.218'
    #con.port = 168
    con.port = 2020
    #con.register(NextValidIdHandler, 'NextValidId')
    con.register(NextValidIdHandler, message.NextValidId)
    con.register(getNextValidOrderId, message)
    con.register(ContractDetailsHandler, 'ContractDetails')
    con.connect()

    #1 = SYSTEM
    #2 = ERROR
    #3 = WARNING
    #4 = INFORMATION
    #5 = DETAIL
    #TODO: fix log level issue
    con.setServerLogLevel(3)

    account = 'aripp268'
    #account = 'aripp004'
    tickId = 10
    reqId = 10
    reqIdHistoricalData0 = 0
    reqIdHistoricalData1 = 1
    reqIdHistoricalData2 = 2
    reqIdHistoricalData3 = 3
    reqIdHistoricalData4 = 4

    reqIdRealTimeBars = 2
    #con.register(update_port, message.UpdatePortfolio)
    #futContract = makeFutContract('ES', 'GLOBEX', '20110617')
    #con.register(printFutQuote, message.TickPrice)
    #con.registerAll(watcher)
    #con.reqMktData(tickId, futContract, '', False)
    ESZ1 = makeFutContract('ES', 'GLOBEX', '20111216')
    futContract = ESZ1

    # request Current Time
    con.register(getCurrentTime, message.CurrentTime)
    con.reqCurrentTime()
    #tickId = tickId + 1
    #print 'start time is %s' % startTime

    # request Historical Bar Data
    #con.registerAll(watcher)
    #con.register(update_fiveminBar, message.HistoricalData)

    # request RealTime Bars Data before request Historical Bar Data
    #con.register(buytest, message.RealtimeBar)
    #con.reqRealTimeBars(reqIdRealTimeBars, futContract, 5, 'TRADES', 0)

    #con.reqHistoricalData(reqIdHistoricalData0, futContract, startTime, '1 D', '1 min', 'TRADES', 0, 1)
    #con.reqIdHistoricalData(reqIdHistoricalData0, futContract, '', '1 D', '1 min', 'TRADES', 0, 1)
    #con.reqHistoricalData(reqIdHistoricalData1, futContract, startTime, '1 D', '5 mins', 'TRADES', 0, 1)
    #con.register(update_openRange, message.HistoricalData)
    #con.reqHistoricalData(reqIdHistoricalData2, futContract, startTime, '2 D', '15 mins', 'TRADES', 0, 1)
    #sleep(1)
    #con.cancelHistoricalData(reqIdHistoricalData1)
    #print fiveminBar

    # get the last time stamp of five minutes Bar
    #latest_t = fiveminBar[len(fiveminBar)-1][0]
    #sleep(1)
    #print latest_t
    # wait 5 minute to record the RealTime Bars Data
    #time_s = mktime(strptime(latest_t, '%Y%m%d %H:%M:%S')) + 2
    #time_s = mktime(strptime(latest_t, '%Y%m%d  %H:%M:%S')) + 5*60
    #time_t = strftime('%Y%m%d %H:%M:%S', localtime(time_s))
    #print startTime

    # record from the beginning of the next five minutes

    # request RealTime Bars Data before request Historical Bar Data
    con.register(update_historicalBar, message.RealtimeBar)
    con.reqRealTimeBars(reqIdRealTimeBars, futContract, 5, 'TRADES', 0)

    #con.unregisterAll(update_openRange)
    #con.reqHistoricalData(reqIdHistoricalData3, futContract, startTime, '10 D', '1 hour', 'TRADES', 0, 1)
    #con.reqHistoricalData(reqIdHistoricalData4, futContract, startTime, '30 D', '1 day', 'TRADES', 0, 1)

    #con.cancelHistoricalData(tickId)
    #tickId = tickId + 1




    # request Level 2 Market Data
    l2numRows = 25
    con.register(updateMktDepth, message.UpdateMktDepth)
    con.reqMktDepth(tickId, futContract, l2numRows)
    tickId = tickId + 1
    con.register(update_openOrder, message.OrderStatus)
    con.register(update_port, message.UpdatePortfolio)
    con.register(update_account, message.UpdateAccountValue)
    con.reqAccountUpdates(1, account)
    #tickId = tickId + 1
    #con.reqAccountUpdates(tickId, account)

    while True:
        printMktDepth()
        sleep(1)
    """
        command = raw_input('\n>>command:')

        if command == 'acount' or command == 'a':
            #con.register(update_account, message.UpdateAccountValue)
            # tickId 1 reserved for Account Updates
            #con.reqAccountUpdates(1, account)
            #tickId = tickId + 1
            print_account()
            sleep(1)
            #con.unregisterAll(print_account)

        if command == 'port' or command == 'p':
            #reqId = 1
            ##con.register(update_port, message.UpdatePortfolio)
            #con.reqAccountUpdates(1, account)
            #tickId = tickId + 1
            print_port()
            sleep(1)
            #print message.items()
            #print message.UpdateAccountValue
            #print message.UpdateAccountValue.value
            #print len(message.UpdateAccountValue.value)

        if command == 'es':
            #ESM1 = makeFutContract('ES', 'GLOBEX', '20110617')
            #futContract = ESM1
            #con.register(printFutQuote, message.TickPrice)
            #con.register(watcher, message)
            #con.reqMktData(tickId, futContract, '', False)
            #tickId = tickId + 1

            # quote?
            #while True:
                #if raw_input("\n") != 'o':
                #con.register(printFutQuote, message.TickPrice)
                #con.reqMktData(tickId, futContract, '', False)
                    #con.register(printMktDepth, message)
                    #printMktDepth()
                    #sleep(0.5)
                #else:
                    #break

            #con.unregisterAll(printFutQuote)
            orderDetails = raw_input("Order Details:\n")
            details = orderDetails.split(" ")

            if len(details) == 3:
                order_t = details[0]
                size_lmt = details[1]
                price_lmt = float(details[2])
                futOrder = makeOrder(details[0], 'LMT', size_lmt, price_lmt)
                con.placeOrder(nextOrderId, futContract, futOrder)
                openOrder[nextOrderId] = [futContract, 'Submitted', 0, size_lmt, price_lmt, order_t, False]
                nextOrderId = nextOrderId + 1

            elif len(details) == 2:
                order_t = details[0]
                size_lmt = 1
                price_lmt = float(details[1])
                futOrder = makeOrder(order_t, 'LMT', size_lmt, price_lmt)
                con.placeOrder(nextOrderId, futContract, futOrder)
                openOrder[nextOrderId] = [futContract, 'Submitted', 0, size_lmt, price_lmt, order_t, False]
                nextOrderId = nextOrderId + 1

            elif len(details) == 1 and details[0] not in ['liquid', 'l']:
                order_t = ''
                if details[0] == 'B' or details[0] == 'Buy' or details[0] == 'b' or details[0] == 'buy':
                    order_t = 'Buy'
                elif details[0] == 'S' or details[0] == 'Sell' or details[0] == 's' or details[0] == 'sell':
                    order_t = 'Sell'

                size_mkt = 1
                # To record current market price
                price_mkt = 0.0
                futOrder = makeOrder(order_t, 'MKT', 1, 0.0)
                con.placeOrder(nextOrderId, futContract, futOrder)
                openOrder[nextOrderId] = [futContract, 'Submitted', 0, size_mkt, price_mkt, order_t, False]
                nextOrderId = nextOrderId + 1

            # liquidation uses market order, there should not be any issue, no tracking for now
            elif details[0] == 'liquid' or details[0] == 'l':
                for ctrt, pos in futPosition.iteritems():
                    if ctrt[0] == 'ES':
                        size_r = pos[0]
                        if size_r > 0:
                            futOrder = makeOrder('SELL', 'MKT', size_r, 0)
                            con.placeOrder(nextOrderId, futContract, futOrder)
                            openOrder[nextOrderId] = [futContract, 'Submitted', 0, size_r, 0, 'Sell', False]
                            nextOrderId = nextOrderId + 1
                        if size_r < 0:
                            futOrder = makeOrder('BUY', 'MKT', -size_r, 0)
                            con.placeOrder(nextOrderId, futContract, futOrder)
                            openOrder[nextOrderId] = [futContract, 'Submitted', 0, -size_r, 0, 'Buy', False]
                            nextOrderId = nextOrderId + 1
            #printMktDepth()
            #print '\n ------------------------------ \n'
            sleep(1)

        if command == 'order status' or command == 'os':
            #con.register(print_open_order, message.OpenOrder)
            #con.reqOpenOrders()
            print_openOrder()
            sleep(1)

        if command == 'exit' or command == 'quit' or command == 'q':
            con.disconnect()
            break;

        else:
            continue
    #con.isConnected()
    """

    """
    while True:
        command = raw_input('\n>>command:')
        con.unregisterAll(print_port)
        con.unregisterAll(print_account)
        con.unregisterAll(print_open_order)
        #con.register(print_open_order, message.OpenOrder)
        #con.register(update_port, message.UpdatePortfolio)
        #con.reqAccountUpdates(tickId, account)

        if command == 'acount' or command == 'a':
            con.register(print_account, message.UpdateAccountValue)
            con.reqAccountUpdates(tickId, account)
            sleep(1)

        if command == 'port' or command == 'p':
            #reqId = 1
            #con.register(update_port, message.UpdatePortfolio)
            #con.reqAccountUpdates(tickId, account)
            sleep(1)
            print_port()
            #print message.items()
            #print message.UpdateAccountValue
            #print message.UpdateAccountValue.value
            #print len(message.UpdateAccountValue.value)

        if command == 'liquid' or command == 'l':
            #con.register(print_port, message.UpdatePortfolio)
            #con.reqAccountUpdates(tickId, account)
            sleep(1)
            print 'which one you want to liquid?'
            contract = raw_input('stock or option or combo?\n')
            if contract == 'stock' or 'S':

        if command == 'options order' or command == 'oo':
            opt = raw_input("Symbol:\n")
            #opt = 'GS 20101217 C160'
            optContract = makeOptContract2(opt)
            while raw_input("Quote:\n") != 'n':
                con.register(printOptQuote, message.TickPrice)
                con.reqMktData(tickId, optContract, '', False)
            con.unregisterAll(printOptQuote)

            orderDetails = raw_input("Order Details:\n")
            details = orderDetails.split(" ")
            if len(details) == 3:
                optOrder = makeOrder(details[0], 'LMT', int(details[1]), float(details[2]))
            elif len(details) == 2:
                optOrder = makeOrder(details[0], 'LMT', 2, float(details[1]))
                con.placeOrder(nextOrderId, optContract, optOrder)
            sleep(1)

        futContract = makeESContract('20110617')
        #con.register(printFutQuote, message.TickPrice)
        con.register(watcher, message)
        con.reqMktData(tickId, futContract, '', False)


            if len(details) == 3:
                futOrder = makeOrder(details[0], 'LMT', details[1], float(details[2]))
                con.placeOrder(nextOrderId, futContract, futOrder)

            elif len(details) == 2:
                futOrder = makeOrder(details[0], 'LMT', 1, float(details[1]))
                con.placeOrder(nextOrderId, futContract, futOrder)

            elif details[0] == "liquid":
                for ctrt, pos in futPosition.iteritems():
                    if ctrt[0] == 'ES':
                        if pos[0] > 0:
                            futContract = makeESContract(ctrt[1])
                            futOrder = makeOrder('SELL', 'MKT', pos[0], 0)
                            con.placeOrder(nextOrderId, futContract, futOrder)
                        if pos[0] < 0:
                            futContract = makeESContract(ctrt[1])
                            futOrder = makeOrder('BUY', 'MKT', -pos[0], 0)
                            con.placeOrder(nextOrderId, futContract, futOrder)
            sleep(1)

        if command == 'combo order' or command == 'co':
            opt1 = raw_input("Short Symbol:\n")
            opt2 = raw_input("Long Symbol:\n")
            #opt1 = 'GS 20101217 P160'
            #opt2 = 'GS 20101217 P165'
            optContract1 = makeOptContract2(opt1)
            optContract2 = makeOptContract2(opt2)

            conId1 = getConId(optContract1)
            conId2 = getConId(optContract2)

            shortLeg = makeOptLeg(conId1, 'SELL')
            longLeg = makeOptLeg(conId2, 'BUY')
            bagContract = makeBagContract('GS', [shortLeg, longLeg])
            orderDetails = raw_input("Order Details:\n")
            details = orderDetails.split(" ")
            if len(details) == 3:
                optOrder = makeOrder(details[0], 'LMT', int(details[1]), float(details[2]))
            else:
                optOrder = makeOrder(details[0], 'LMT', 2, float(details[1]))
            #buyOrder = makeOrder('BUY', 2, 0.02)
            con.placeOrder(nextOrderId, bagContract, buyOrder)
            sleep(1)

        if command == 'option chain' or command == 'oc':
            reqId = 2
            sym = raw_input('Please input the symbol: ')
            optContract = makeOptContract(sym)
            con.register(print_option_chain, message.ContractDetails)
            con.reqContractDetails(reqId, optContract)
            sleep(5)
            con.unregister(print_option_chain, message.ContractDetails)

        if command == 'order status' or command == 'os':
            con.register(print_open_order, message.OpenOrder)
            con.reqOpenOrders()
            sleep(1)

        if command == 'exit' or command == 'quit' or command == 'q':
            con.disconnect()
            break;

        else:
            continue

        #con.reqAccountUpdates(tickId,'aripp268')
        #tickId = tickId + 1
        #con.reqManagedAccts()
        #con.reqAllOpenOrders()
        #con.placeOrder(tickId, stkContract, stkOrder)
        #stkContract.m_orderType = 'MKT'
        #stkContract.m_totalQuantity = 50
        #tickId = tickId + 1
        #contractTuple2 = ('AMZN', 'STK', 'SMART', 'USD', '', 0.0, '')
        #stkContract2 = makeStkContract(contractTuple2)
        #stkOrder2 = makeStkOrder('SELL', orderId, 'GTC', 'MKT', 157.40, 100)
        #con.placeOrder(tickId, stkContract2, stkOrder2)
        ##con.reqRealTimeBars(tickId, stkContract, '1 S', 'TRADES', 1)
        #sleep(1000)
        """
    con.disconnect()
    #sleep(1)
